package com.trainoo.novel.controller;

import com.trainoo.novel.constant.NovelConstant;
import com.trainoo.novel.crawler.NovelCrawlerAdapter;
import com.trainoo.novel.model.Book;
import com.trainoo.novel.model.Chapter;
import com.trainoo.novel.model.WebSource;
import com.trainoo.novel.service.NovelAdapterService;
import com.trainoo.novel.util.SessionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class NovelController {

    private static Logger logger = LoggerFactory.getLogger(NovelController.class);

    @Value("${source.website}")
    private String source;

    @RequestMapping(value = "/hot", method = RequestMethod.POST)
    @ResponseBody
    public List<Chapter> hot() {
        logger.info("请求获取热门图书信息");
        NovelCrawlerAdapter crawler = NovelAdapterService.getAvailNovelAdapter();
        List<Chapter> resultList = null;
        try {
            resultList = crawler.hotBookList();
            logger.info("查询到热门图书[{}]本", resultList.size());
        } catch (Exception e) {
            logger.error("获取热门列表异常，异常信息：{}", e);
        }
        return resultList;
    }

    @RequestMapping(value = "/book/{id}")
    public String bookInfo(@PathVariable String id, ModelMap map) {
        logger.info("加载图书详情,图书[{}]", id);
        NovelCrawlerAdapter crawler = NovelAdapterService.getAvailNovelAdapter();
        Book bookInfo = crawler.crawlBookInfo(id);
        map.addAttribute("book", bookInfo);
        return "chapters";
    }

    @RequestMapping(value = "chapter.html")
    public String read(@RequestParam String url, ModelMap map) {
        logger.info("加载内容,图书[{}]", url);
        // 针对第三方(sodu)链接
        if (url.startsWith("http")){
            Chapter chapter = new Chapter("", url);
            map.addAttribute("chapter", chapter);
            return "thirdPart";
        }
        // 针对本地链接
        url = url.replace("/book/", "");
        try {
            NovelCrawlerAdapter crawler = NovelAdapterService.getAvailNovelAdapter();
            Chapter chapter = crawler.readChapter(url);
            map.addAttribute("chapter", chapter);
        } catch (Exception e) {
            map.addAttribute("errorMsg", "章节信息错误，请重试！");
            logger.error("图书[{}]信息错误,异常信息：{}", url, e);
        }
        return "content";
    }

    @RequestMapping(value = "/search/{bookName}/{page}")
    public String search(@PathVariable String bookName, @PathVariable String page, ModelMap map) {
        logger.info("开始搜索[{}],分页[{}]", bookName, page);
        NovelCrawlerAdapter crawler = NovelAdapterService.getAvailNovelAdapter();
        Map<String, String> contentMap = new HashMap<>();
        contentMap.put(NovelConstant.KEY_WORD, bookName);
        contentMap.put(NovelConstant.PAGE, page);
        try {
            List<Book> resultList = crawler.searchBook(contentMap);
            logger.info("查询返回结果数量：{}", resultList.size());
            if (resultList.size() == 0) {
                map.addAttribute("errorMsg", MessageFormat.format("暂无该图书[{0}]，可尝试换源后重试", bookName));
            } else {
                map.addAttribute("resultList", resultList);
                map.addAttribute("bookName", bookName);
                map.addAttribute("pageInfo", contentMap.get("pageInfo"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            map.addAttribute("errorMsg", MessageFormat.format("暂无该图书[{0}]，可尝试换源后重试", bookName));
            logger.error("找不到该图书[{}]信息", bookName);
        }
        return "searchList";
    }

    @RequestMapping(value = "/searchPhp", method = RequestMethod.GET)
    public String searchPhp(HttpServletRequest request, ModelMap map) {
        String keyword = request.getParameter("keyword");
        String page = request.getParameter("page");
        try {
            if (page == null) {
                page = "0";
            }
            return "redirect:search/" + keyword + "/" + page;
        } catch (Exception e) {
            e.printStackTrace();
            map.addAttribute("errorMsg", "找不到该图书信息呢！");
            logger.error("找不到该图书[{}]信息", keyword);
        }
        return "searchList";
    }

    @RequestMapping(value = "/changeSource.html", method = RequestMethod.GET)
    public String changeSource(ModelMap map) {
        List<WebSource> sourceList = new ArrayList<>();
        if (null != source) {
            String[] webSources = source.split("\\|");
            for (String webSource : webSources) {
                String[] value = webSource.split(";");
                HttpSession session = SessionUtil.getSession();
                String curSource = (String) session.getAttribute(NovelConstant.WEB_SOURCE);
                if (value[0].equals(curSource)) {
                    sourceList.add(new WebSource(value[0], value[1], 1));
                } else {
                    sourceList.add(new WebSource(value[0], value[1], 0));
                }
            }
        }
        map.addAttribute("sourceList", sourceList);
        return "changeSource";
    }

    @RequestMapping(value = "/changeSource/{curSource}")
    public String doChangeSource(@PathVariable("curSource") String curSource, ModelMap map) {
        logger.info("请求切换图书源：{}", curSource);
        List<WebSource> sourceList = new ArrayList<>();
        if (null != source) {
            String[] webSources = source.split("\\|");
            for (String webSource : webSources) {
                String[] value = webSource.split(";");
                if (value[0].equals(curSource)) {
                    SessionUtil.getSession().setAttribute(NovelConstant.WEB_SOURCE, curSource);
                    sourceList.add(new WebSource(value[0], value[1], 1));
                } else {
                    sourceList.add(new WebSource(value[0], value[1], 0));
                }
            }
        }
        map.addAttribute("successMsg", "切换图书来源成功");
        map.addAttribute("sourceList", sourceList);
        return "changeSource";
    }
}
